package cn.tedu.mall.search.service.impl;

import cn.tedu.mall.common.restful.JsonPage;
import cn.tedu.mall.pojo.product.model.Spu;
import cn.tedu.mall.pojo.search.entity.SpuForElastic;
import cn.tedu.mall.product.service.front.IForFrontSpuService;
import cn.tedu.mall.search.repository.SpuForElasticRepository;
import cn.tedu.mall.search.service.ISearchService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class SearchServiceImpl implements ISearchService {

    // dubbo调用product模块的分页查询所有Spu的方法
    @DubboReference
    private IForFrontSpuService dubboSpuService;
    @Autowired
    private SpuForElasticRepository spuRepository;

    @Override
    public void loadSpuByPage() {
        // 基本思路:dubbo调用分页查询,获取数据库中spu信息
        // 然后将这页数据批量新增到ES
        // 需要考虑循环如何编写
        // 分页查询返回值JsonPage中是包含本次查询的总页数的,总页数就是循环的次数
        // 但是需要先运行一次查询,才能知道这个值,符合"先运行,后判断"的规则,所以使用do-while
        int i=1;  // 循环变量,从1开始,因为分页查询页码从1开始,可以直接使用i
        int page; // 总页数,也是循环条件,会在循环运行完第一次之后赋值

        do{
            // dubbo调用product模块分页查询spu信息
            JsonPage<Spu> spus=dubboSpuService.getSpuByPage(i,2);
            // 上面完成的数据库查询,返回集合的泛型不是我们需要的SpuForElastic
            // 那么我们就需要先实例化SpuForElastic泛型的集合,然后再为这个集合赋值
            List<SpuForElastic> esSpus=new ArrayList<>();
            // 遍历分页数据spus,将集合中的元素转换
            for(Spu spu : spus.getList()){
                SpuForElastic esSpu=new SpuForElastic();
                BeanUtils.copyProperties(spu,esSpu);
                // 将赋好值的esSpu对象新增到esSpus集合中
                esSpus.add(esSpu);
            }
            // esSpus集合中已经包含了本页的数据,利用批量新增方法,新增到ES中
            spuRepository.saveAll(esSpus);
            log.info("信息加载成功!第{}页",i);
            // 循环变量自增
            i++;
            // 为page总页数赋值,确定循环次数
            page=spus.getTotalPage();
        }while (i<=page);
    }

    // 根据用户输入的关键字对ES进行搜索的方法
    @Override
    public JsonPage<SpuForElastic> search(
            String keyword, Integer page, Integer pageSize) {
        // 根据参数进行分页查询,因为SpringData页码从0开始,所以page-1
        Page<SpuForElastic> spus=spuRepository.querySearch(
                            keyword, PageRequest.of(page-1,pageSize));
        // 现在查询获取的是Page类型,我们需要转换为JsonPage才能返回
        JsonPage<SpuForElastic> jsonPage=new JsonPage<>();
        // 赋值分页信息
        jsonPage.setPage(page);
        jsonPage.setPageSize(pageSize);
        jsonPage.setTotal(spus.getTotalElements());
        jsonPage.setTotalPage(spus.getTotalPages());
        // 赋值分页数据
        jsonPage.setList(spus.getContent());
        // 最后别忘了返回
        return jsonPage;
    }
}
